import sys
import csv
import graph
import random
import copy
import numpy as np
from munkres import Munkres, print_matrix

def PCS(w2l_dist, benifit_list, w_num):
    MAX_INT = sys.maxsize
    sensed_locs_list = [0,0,0,0,0]
    sensed_locs_cnt = 0
    cost = 0
    benifit = 0
    utility = 0

    w_seq = []
    for i in range(w_num):
        w_seq.append(i)
    random.shuffle(w_seq)
    for w in w_seq:
        for i in range(len(sensed_locs_list)):
            if w2l_dist[w][i] < MAX_INT/10 and sensed_locs_list[i] == 0:
                cost += w2l_dist[w][i]
                benifit += benifit_list[i]
                utility += benifit_list[i]/w2l_dist[w][i]
                sensed_locs_cnt += 1
                sensed_locs_list[i] = 1
                break
    with open('./result/'+str(w_num)+'/PCS.csv', 'a+') as csvfile:
        spamwriter = csv.writer(csvfile)
        spamwriter.writerow([cost,benifit,utility,sensed_locs_cnt])

def NLF(w2l_dist, benifit_list, w_num):
    MAX_INT = sys.maxsize
    sensed_locs_list = [0,0,0,0,0]
    sensed_locs_cnt = 0
    cost = 0
    benifit = 0
    utility = 0
    w_seq = []
    for i in range(w_num):
        w_seq.append(i)
    random.shuffle(w_seq)

    for w in w_seq:
        min_dist = MAX_INT/10
        min_w = -1
        min_l = -1
        for l in range(len(sensed_locs_list)):
            if w2l_dist[w][l] < min_dist and sensed_locs_list[l] == 0:
                min_dist = w2l_dist[w][l]
                min_w = w
                min_l = l
        if min_w > -1:
            cost += w2l_dist[min_w][min_l]
            benifit += benifit_list[min_l]
            utility += benifit_list[min_l]/w2l_dist[min_w][min_l]
            sensed_locs_cnt += 1
            sensed_locs_list[min_l] = 1

    with open('./result/'+str(w_num)+'/NLF.csv', 'a+') as csvfile:
        spamwriter = csv.writer(csvfile)
        spamwriter.writerow([cost,benifit,utility,sensed_locs_cnt])

def NWF(l2wdist, benifit_list, w_num):
    MAX_INT = sys.maxsize
    assigned_worker_list = [0]*w_num
    sensed_locs_cnt = 0
    cost = 0
    benifit = 0
    utility = 0

    for l in range(len(l2wdist)):
        min_dist = MAX_INT/10
        min_w = -1
        for i in range(len(assigned_worker_list)):
            if l2wdist[l][i] < min_dist and assigned_worker_list[i] == 0:
                min_dist = l2wdist[l][i]
                min_w = i
        if min_w > -1:
            cost += l2wdist[l][min_w]
            benifit += benifit_list[l]
            utility += benifit_list[l]/l2wdist[l][min_w]
            sensed_locs_cnt += 1
            assigned_worker_list[min_w] = 1

    with open('./result/'+str(w_num)+'/NWF.csv', 'a+') as csvfile:
        spamwriter = csv.writer(csvfile)
        spamwriter.writerow([cost,benifit,utility,sensed_locs_cnt])

def MPLF(l2wdist, benifit_list, w_num):
    MAX_INT = sys.maxsize
    assigned_worker_list = [0]*w_num
    sensed_locs_cnt = 0
    cost = 0
    benifit = 0
    utility = 0

    for l in range(len(l2wdist)):
        for w in range(len(assigned_worker_list)):
            if l2wdist[l][w] < MAX_INT/10 and assigned_worker_list[w] == 0:
                cost += l2wdist[l][w]
                benifit += benifit_list[l]
                utility += benifit_list[l]/l2wdist[l][w]
                sensed_locs_cnt += 1
                assigned_worker_list[w] = 1
                break


    with open('./result/'+str(w_num)+'/MPLF.csv', 'a+') as csvfile:
        spamwriter = csv.writer(csvfile)
        spamwriter.writerow([cost,benifit,utility,sensed_locs_cnt])

def my_method(w2l_dist, benifit_list):
    MAX_INT = sys.maxsize
    MAX_B = 100
    sensed_locs_cnt = 0
    cost = 0
    benifit = 0
    utility = 0

    w_num = len(w2l_dist)
    l_num = 5
    if w_num < 5:
        for i in range(w_num, l_num):
            w2l_dist[i] = [MAX_INT,MAX_INT,MAX_INT,MAX_INT,MAX_INT]
    elif w_num > 5:
        for j in range(l_num,w_num):
                benifit_list.append(0)
        for i in range(w_num):
            for j in range(l_num,w_num):
                w2l_dist[i].append(MAX_INT)

    w_num2 = len(w2l_dist)
    graph = []
    for i in range(w_num2):
        graph.append(copy.deepcopy(w2l_dist[i]))

    for i in range(w_num2):
        for j in range(w_num2):
            if graph[i][j] > MAX_INT/10:
                graph[i][j] = 0
            else:
                if w2l_dist[i][j] < 1:
                    w2l_dist[i][j] = 1
                graph[i][j] = benifit_list[j]/w2l_dist[i][j]

    cost_matrix = []
    for row in graph:
        cost_row = []
        for col in row:
            cost_row += [MAX_B - col]
        cost_matrix += [cost_row]
    
    m = Munkres()
    indexes = m.compute(cost_matrix)

    for index in indexes:
        w = index[0]
        i = index[1]
        if w2l_dist[w][i]< MAX_INT/10:
            cost += w2l_dist[w][i]
            benifit += benifit_list[i]
            utility += graph[w][i]
            sensed_locs_cnt += 1
    with open('./result/'+str(w_num)+'/my_method.csv', 'a+') as csvfile:
        spamwriter = csv.writer(csvfile)
        spamwriter.writerow([cost,benifit,utility,sensed_locs_cnt])

def statistics_mean():
    methods=['NLF','MPLF','PCS','NWF','my_method']
    # workers=['1','3','5','7','9','11']
    workers=['1','3','5','9','15','30','50','100']
    statistics = {}
    for m in methods:
        statistics[m] = {}
        statistics[m]['cost'] = []
        statistics[m]['benifit'] = []
        statistics[m]['utility'] = []
        statistics[m]['cover'] = []
        for w in workers:
            cost = 0.0
            benifit = 0.0
            utility = 0.0
            s_l_c = 0
            cnt = 0
            filename = './result/'+w+'/'+m+'.csv'
            with open(filename, "r") as f:
                reader = csv.reader(f)
                for row in reader:
                    cnt += 1
                    cost += float(row[0])
                    benifit += float(row[1])
                    utility += float(row[2])
                    s_l_c += float(row[3])
            mean_cost = cost/cnt
            mean_benifit = benifit/cnt
            mean_utility = utility/cnt
            mean_cover = s_l_c/cnt*20
            statistics[m]['cost'].append(mean_cost)
            statistics[m]['benifit'].append(mean_benifit)
            statistics[m]['utility'].append(mean_utility)
            statistics[m]['cover'].append(mean_cover)

    with open('./result/stat2_cost.csv', 'a+') as csvfile:
            spamwriter = csv.writer(csvfile)
            for m in statistics:
                spamwriter.writerow([m,statistics[m]['cost']])

    with open('./result/stat2_beni.csv', 'a+') as csvfile:
            spamwriter = csv.writer(csvfile)
            for m in statistics:
                spamwriter.writerow([m,statistics[m]['benifit']])

    with open('./result/stat2_utility.csv', 'a+') as csvfile:
            spamwriter = csv.writer(csvfile)
            for m in statistics:
                spamwriter.writerow([m,statistics[m]['utility']])    

    with open('./result/stat2_cover.csv', 'a+') as csvfile:
            spamwriter = csv.writer(csvfile)
            for m in statistics:
                spamwriter.writerow([m,statistics[m]['cover']])    
            # with open('./result/stat.csv', 'a+') as csvfile:
            #     spamwriter = csv.writer(csvfile)
            #     spamwriter.writerow([filename,mean_cost,mean_benifit,mean_utility,mean_cover])


if __name__ == '__main__':
    '''
    test_obj = [("5583_5583", 5583), ('128_128', 128), ('4072_4072', 4072), ("15_15", 15), 
                ("17_680", 680), ("1779_1779", 1779),('940_940',940),('1051_1051',1051),('5501_4212',4212),('5808_654',654)]
    # test_time = 10

    #for w_num in range(1,6,2):
    #for w_num in range(9,16,6):
    #for w_num in range(30,51,20):
    for w_num in range(100,101,20):
        for test_case in test_obj:
            filename = './testcase/t5/'+test_case[0]+'.csv'
            with open(filename, "r") as f:
                reader = csv.reader(f)
                info = []
                for row in reader:
                    for i in range(len(row)):
                        row[i] = float(row[i])
                    info.append(row)
            w2l_dist = {}
            for i in range(w_num):
                w2l_dist[i] = info[i]
            benifit_list = info[100]
            l = []
            for i in range(w_num):
                l.append(copy.deepcopy(w2l_dist[i]))
            l2w_dist = list(map(list,zip(*l)))

      
            NLF(w2l_dist, benifit_list, w_num)
            PCS(w2l_dist, benifit_list, w_num)
            NWF(l2w_dist,benifit_list,w_num)
            MPLF(l2w_dist, benifit_list, w_num)
            my_method(w2l_dist,benifit_list)'''

    statistics_mean()    
